﻿


crucible.SurrogateNode = function (data) {
    crucible.Node.call(this, data);

    var self = this;
    self.original = null;
    self.hooks = [];

    this.Comments = ko.observableArray();
       
    self.newComment = ko.observable();
    self.CommentBoxVisible = ko.observable(false);
    self.CommentBoxFocused = ko.observable(false);


    self.BodyHasChildren = ko.computed(function () {
        var test = /(\{\{\[([0-9]+)\]([^}]+)\}\})/g;
        return test.test(self.Body());
    });

    self.ShowSourceBtn = ko.computed(function () {
        return !self.Source() && (self.Type() == crucible.NodeType.interpretation ||
            self.Type() == crucible.NodeType.source ||
            (self.Type() == crucible.NodeType.assertion && !self.BodyHasChildren())
        );
    });


    self.adopt = function (node) {
        if (self.original) {
            releaseOriginal();
        }

        adoptOriginal(node);
    };

    function adoptOriginal(node) {
        self.original = node;

        // these will never change
        self.Id = node.Id;
        self.AddedBy(node.AddedBy());
        self.IsEditing(!node.Published());

        // Subscribe to these so they are synced immediately
        setAndHook("Title");
        setAndHook("Body");
        setAndHook("Published");
        setAndHook("Type");
        setAndHook("Source");
        setAndHook("Link");
        setAndHook("Logic");
        setAndHook("Agreement");

        // remember to sync these manually at the end
        self.hydrated = node.hydrated;
        self.CommentBoxVisible(false);

    }
        

    function releaseOriginal() {
        var orig = self.original,
            sub;

        // dispose of all subscriptions
        while (sub = self.hooks.pop()) {
            sub.dispose();
        }

        // put manual properties back on the original
        orig.hydrated = orig.hydrated || self.hydrated;
        //orig.CommentBoxVisible(self.CommentBoxVisible());

        // blank the original pointer, we're done
        self.original = null;
    }

    function setAndHook(observable) {
        var sub;

        self[observable](self.original[observable]());
        sub = self[observable].subscribe(function (newVal) {
            self.original[observable](newVal);
        });
        self.hooks.push(sub);
    }

};

crucible.SurrogateNode.prototype = Object.create(crucible.Node.prototype);

crucible.SurrogateNode.prototype.freshData = function (data, parents) {
    crucible.Node.prototype.freshData.call(this, data);
    this.original.setOtherParents(parents);
};


crucible.SurrogateNode.prototype.startCommenting = function () {
    if (!(crucible.userId > 0)) {
        crucible.raiseError("You must be logged in to comment.", true);
        return;
    }

    this.CommentBoxVisible(true);
    this.CommentBoxFocused(true);
};

crucible.SurrogateNode.prototype.agreeUp = function () {
    var current = this.Agreement(),
        self = this;
    if (current < 2) {
        datacontext.putNodeVote(this.Id, current + 1, this.Logic(), function () {
            self.Agreement(current + 1);
        });
    }
};

crucible.SurrogateNode.prototype.agreeDown = function () {
    var current = this.Agreement(),
        self = this;
    if (current > -2) {
        datacontext.putNodeVote(this.Id, current - 1, this.Logic(), function () {
            self.Agreement(current - 1);
        });
    }
};

crucible.SurrogateNode.prototype.logicUp = function () {
    var current = this.Logic(),
        self = this;
    if (current < 2) {
        datacontext.putNodeVote(this.Id, this.Agreement(), current + 1, function () {
            self.Logic(current + 1);
        });
    }
};

crucible.SurrogateNode.prototype.logicDown = function () {
    var current = this.Logic(),
        self = this;
    if (current > -2) {
        datacontext.putNodeVote(this.Id, this.Agreement(), current - 1, function () {
            self.Logic(current - 1);
        });
    }
};